package com.example.micro.thread.queue.pool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 面试题：实现生产者、消费者场景。
 * <p>
 * 假设现在有一个任务调度系统负责处理数据，A线程负责从DB里拉待处理的任务放到队列，B线程组负责从队列中处理任务；
 * 由于任务处理量较大，B线程组会将任务进行并行处理。当所有子线程处理完成后，由B线程汇总结果并统一入库
 * <p>
 * 要求：
 * A线程组负责生产数据data，B线程组负责消费data数据，A、B线程组要实现阻塞；
 * 尽量考虑异常场景的处理；
 * B线程组的一个处理线程在获取到一个数后，需要再拆分5个子线程并行处理是数据，当5个子线程全部处理完成，B的处理线程将结果合并；
 * 请尽量考虑异常场景的处理；
 * <p>
 * 考核点：多线程、锁、异常设计；
 * 考核标准：可运行并且满足所有题干要求。
 *
 * @author Code Farmer
 * @create 2021/3/29 1:11 上午
 */

/**
 * 解决方式：线程池+阻塞队列
 */
public class ProducerCustomerMain {

    public static void main(String[] args) {
        ArrayBlockingQueue<Integer> dataQueue = new ArrayBlockingQueue<>(20); //数据队列，容量20
        ExecutorService threadPool = Executors.newCachedThreadPool();  //线程池

        System.out.println("生产者线程组启动");
        //生产者线程启动
        for (int i = 0; i < 7; i++) {
            threadPool.submit(new ThreadProducer(dataQueue));
        }

        System.out.println("消费者线程组启动");
        //消费者线程启动
        for (int i = 0; i < 3; i++) {
            threadPool.submit(new ThreadCustomer(dataQueue));
        }

        threadPool.shutdown();
    }

}
